#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_err.h"

#include "nvs.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#include "userwifi.h"

static const char *TAG = "main";
#define LOG_LOCAL_LEVEL  ESP_LOG_DEBUG

#define GPIO_OUTPUT_LED 2
#define GPIO_OUTPUT_IO_R 15
#define GPIO_OUTPUT_IO_G 12
#define GPIO_OUTPUT_IO_B 13
#define GPIO_OUTPUT_PIN_SEL ((1UL << GPIO_OUTPUT_IO_R) | (1UL << GPIO_OUTPUT_IO_G) | (1UL << GPIO_OUTPUT_IO_B) | (1UL << GPIO_OUTPUT_LED))
#define GPIO_INPUT_K1 4
#define GPIO_INPUT_PIN_SEL ((1UL << GPIO_INPUT_K1))

static xQueueHandle gpio_evt_queue = NULL;

static void gpio_isr_handler(void *arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

void Gpio_Init(void)
{
    gpio_config_t IO_config;
    IO_config.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    IO_config.mode = GPIO_MODE_DEF_OUTPUT;
    IO_config.pull_up_en = GPIO_PULLUP_ENABLE;
    IO_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
    IO_config.intr_type = GPIO_INTR_DISABLE;
    gpio_config(&IO_config);

    IO_config.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    IO_config.mode = GPIO_MODE_DEF_INPUT;
    IO_config.pull_up_en = GPIO_PULLUP_DISABLE;
    IO_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
    IO_config.intr_type = GPIO_INTR_NEGEDGE;
    gpio_config(&IO_config);

    gpio_evt_queue = xQueueCreate(10,sizeof(uint32_t));
    gpio_install_isr_service(0);
    gpio_isr_handler_add(GPIO_INPUT_K1, gpio_isr_handler, (void *) GPIO_INPUT_K1);    

    gpio_set_level(GPIO_OUTPUT_IO_R, 0);
    gpio_set_level(GPIO_OUTPUT_IO_G, 0);
    gpio_set_level(GPIO_OUTPUT_IO_B, 0);
    gpio_set_level(GPIO_OUTPUT_LED, 1);
}

static void gpio_listen_task(void *arg)
{
    uint32_t io_nun;
    ESP_LOGI(TAG,"start gpio_listen");
    while (1)
    {
        if (xQueueReceive(gpio_evt_queue, &io_nun, portMAX_DELAY)) {
            if(io_nun == GPIO_INPUT_K1){
                ESP_LOGI(TAG,"start Smart_Config");
                Smart_Config();
            }
        }
    }
}

static void led_task(void *arg)
{
    Gpio_Init();
    while (1)
    {
        gpio_set_level(GPIO_OUTPUT_LED, 0);
        vTaskDelay(500 / portTICK_RATE_MS);
        gpio_set_level(GPIO_OUTPUT_LED, 1);
        vTaskDelay(500 / portTICK_RATE_MS);
    }
}



void app_main()
{
    ESP_LOGE(TAG,"ESP_LOGE");
    ESP_LOGW(TAG,"ESP_LOGW");
    ESP_LOGI(TAG,"ESP_LOGI");
    ESP_LOGD(TAG,"ESP_LOGD");
    ESP_LOGV(TAG,"ESP_LOGV");

    ESP_LOGI(TAG,"start Gpio_Init");
    Gpio_Init();

    ESP_LOGI(TAG,"start user_Wifi_Init");
    user_Wifi_Init();

    ESP_LOGI(TAG,"start led_task");
    xTaskCreate(led_task, "led_task", 1024, NULL, 20, NULL);

    ESP_LOGI(TAG,"start gpio_listen_task");
    xTaskCreate(gpio_listen_task, "gpio_listen_task", 1024*10, NULL, 20, NULL);

}
